package com.booter.webflux.config;

import com.mongodb.ConnectionString;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.ReactiveMongoDatabaseFactory;
import org.springframework.data.mongodb.ReactiveMongoTransactionManager;
import org.springframework.data.mongodb.core.ReactiveMongoTemplate;
import org.springframework.data.mongodb.core.SimpleReactiveMongoDatabaseFactory;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;

@EnableMongoRepositories(basePackages = {"com.booter.webflux.repository.mongo"})
@Configuration
public class MongoConfig {

    @Value("${spring.data.mongodb.uri}")
    private String mongoUri;

//    @Autowired
//    private MongoMappingContext mongoMappingContext;

    @Bean
    public ReactiveMongoDatabaseFactory mongoDatabaseFactory() {
        return new SimpleReactiveMongoDatabaseFactory(new ConnectionString(this.mongoUri));
    }


    @Bean
    public ReactiveMongoTemplate reactiveMongoTemplate(@Qualifier("mongoDatabaseFactory")
                                                               ReactiveMongoDatabaseFactory databaseFactory) {
//        MappingMongoConverter mongoConverter = new MappingMongoConverter(databaseFactory, this.mongoMappingContext);
//        mongoConverter.setMapKeyDotReplacement("_");
//        mongoConverter.afterPropertiesSet();
        return new ReactiveMongoTemplate(databaseFactory);
    }

    /**
     * 用于开启mongo事务，Spring Data MongoDB是使用ReactiveMongoTransactionManager。它创建会话并管理事务，以便在托管事务中执行的代码参与多文档事务
     *
     * @param databaseFactory
     * @return
     */
    @Bean
    public ReactiveMongoTransactionManager reactiveMongoTransactionManager(@Qualifier("mongoDatabaseFactory")
                                                                                   ReactiveMongoDatabaseFactory databaseFactory) {
        return new ReactiveMongoTransactionManager(databaseFactory);
    }

    /**
     *
     *
     ReactiveTransactionManager tm = new ReactiveMongoTransactionManager(databaseFactory);
     ReactiveMongoTemplate template = …
     template.setSessionSynchronization(ALWAYS);

     TransactionalOperator rxtx = TransactionalOperator.create(tm);

     Mono<Void> atomic = template.update(Step.class)
     .apply(Update.set("state", …))
     .then(template.insert(EventLog.class).one(new EventLog(…))
     .as(rxtx::transactional)
     .then();
     *
     */
}
